// component/swiperBar/swiperBar.js
const sysInfo = wx.getSystemInfoSync()
const scaleRate = sysInfo.windowWidth / 750;
const delay = 20;
Component({
  /**
   * 组件的属性列表
   */
  externalClasses: ['className'],
  properties: {
    height: {
      type: String,
      value: '120rpx'
    },
    left: {
      type: String,
      value: '#e9d24f'
    },
    right: {
      type: String,
      value: '#339f6d'
    },
    leftText: {
      type: String,
      value: '星标'
    },
    leftStatus: {
      type: Boolean,
      value: false,
    },
    rightText: {
      type: String,
      value: '完成'
    },
    rightStatus: {
      type: Boolean,
      value: false
    },
    title: {
      type: String,
      value: ""
    },
    background: {
      type: String,
      value: "white"
    },
    leftEffect: {
      type: Boolean,
      value: true
    },
    rightEffect: {
      type: Boolean,
      value: true
    },
    star: {
      type: Boolean,
      value: false
    },
    starColor: {
      type: String,
      value: '#e9d24f'
    }
    //leftevent:左边触发事件
    //rightevent:右边触发事件
    //ymove:上下滑动事件
  },

  /**
   * 组件的初始数据
   */
  data: {
    bodyLeft: 0,
    withAnime: false,
    eventAenable: false,
    eventBenable: false,
    dragRange: 350,
    minRange: 30,
    leftS: false,
    rightS: false,
    rangeEnable: false,
    moveInfo: {
      startTouch: false,
      isMove: false,
      yMove: false,
      startX: 0,
      startY: 0,
      lastX: 0,
      speed: 0,
      lastTime: null,
    },
    delayTimer: null,
    delayHandler: null
  },
  lifetimes:{
    detached(){
      clearTimeout(this.data.delayTimer);
      clearTimeout(this.data.delayHandler);
      clearTimeout(this.data.withAnime);
    }
  },
  observers: {
    'rightStatus': function(rightS) {
      if (this.data.rightEffect) {
        setTimeout(() => {
          this.setData({
            rightS
          })
        }, 1500)
      } else {
        this.setData({
          rightS
        })
      }
    },
    'leftStatus': function(leftS) {
      if (this.data.leftEffect) {
        setTimeout(() => {
          this.setData({
            leftS
          })
        }, 1500)
      } else {
        this.setData({
          leftS
        })
      }
    }
  },
  /**
   * 组件的方法列表
   */
  methods: {
    touchstart(e) {
      if (this.data.withAnime) return;
      this.data.moveInfo = {
        startTouch: true,
        isMove: false,
        yMove: false,
        startX: e.touches[0].clientX,
        startY: e.touches[0].clientY,
        currentX: 0,
        lastTime: e.timeStamp,
        speed: 0,
        lastX: e.touches[0].clientX
      }
      this.setData({
        rangeEnable: false
      })

    },
    touchmove(e) {
      if (!this.data.delayTimer) {
        clearTimeout(this.data.delayHandler);
        this.data.delayTimer = setTimeout(() => {
          this.data.delayTimer = null
        }, delay)
        this.dealDrag(e)
      } else {
        if (this.data.delayHandler) clearTimeout(this.data.delayHandler);
        this.data.delayHandler = setTimeout(this.dealDrag.bind(this), delay, e);
      }
    },
    touchend(e) {
      if (!e.touches.length && this.data.moveInfo.startTouch) {
        if (this.data.moveInfo.yMove) {
          this.triggerEvent('touchend', {}, {
            bubbles: true,
            composed: true
          })
          return;
        } else if (!this.data.moveInfo.yMove && !this.data.moveInfo.isMove) {
          this.triggerEvent('tap', {}, {
            bubbles: true,
            composed: true
          })
        }
        this.moveMotionEnd();
        if ((this.data.rangeEnable || this.data.moveInfo.speed > 0.4) && this.data.bodyLeft > 0) {
          this.setData({
            eventAenable: true
          })
          this.triggerEvent('leftevent');
          setTimeout(() => {
            this.setData({
              eventAenable: false,
            })
          }, 1000)
        } else if ((this.data.rangeEnable || this.data.moveInfo.speed < -0.4) && this.data.bodyLeft < 0) {
          this.setData({
            eventBenable: true
          })
          this.triggerEvent('rightevent');
          setTimeout(() => {
            this.setData({
              eventBenable: false
            })
          }, 1000)
        }
        this.resetPosition();
        if ((this.data.eventAenable && this.data.leftEffect) || (this.data.rightEffect && this.data.eventBenable)) {
          if (this.data.withAnime) clearTimeout(this.data.withAnime)
          this.setData({
            withAnime: setTimeout(() => {
              this.setData({
                withAnime: false
              })
            }, 1500)
          })

        }
      }
    },
    dealDrag(e) {
      const leftRange = this.data.left ? this.data.dragRange : 0;
      const rightRange = this.data.right ? -this.data.dragRange : 0;
      if (this.data.moveInfo.startTouch && this.data.moveInfo.yMove) {
        this.triggerEvent('touchmove', {
          y: e.touches[0].clientY
        }, {
          bubbles: true,
          composed: true
        })
        return;
      }
      let rangeEnable = false;
      this.data.moveInfo.speed = (e.touches[0].clientX - this.data.moveInfo.lastX) / (e.timeStamp - this.data.moveInfo.lastTime);
      this.data.moveInfo.lastX = e.touches[0].clientX;
      this.data.moveInfo.lastTime = e.timeStamp;
      if (this.data.moveInfo.startTouch && !this.data.moveInfo.isMove) {
        const disX = getDistance(e.touches[0].clientX, this.data.moveInfo.startY, this.data.moveInfo.startX, this.data.moveInfo.startY);
        const disY = getDistance(this.data.moveInfo.startX, e.touches[0].clientY, this.data.moveInfo.startX, this.data.moveInfo.startY);
        if (disX > 10) this.data.moveInfo.isMove = true;
        else if (disY > 10) {
          this.data.moveInfo.yMove = true;
          this.triggerEvent('touchstart', {
            y: e.touches[0].clientY
          }, {
            bubbles: true,
            composed: true
          })
          return;
        }
      } else if (this.data.moveInfo.startTouch && this.data.moveInfo.isMove) {
        let tempLeft = e.touches[0].clientX - this.data.moveInfo.startX;
        const deltaDistance = this.data.dragRange * scaleRate - Math.abs(tempLeft);
        if (deltaDistance < this.data.minRange) {
          rangeEnable = true;
          if (tempLeft > 0) {
            tempLeft = (this.data.dragRange - this.data.minRange) * scaleRate - deltaDistance / 2
          } else {
            tempLeft = -(this.data.dragRange - this.data.minRange) * scaleRate + deltaDistance / 2
          }
        }
        if (tempLeft > leftRange * scaleRate) tempLeft = leftRange * scaleRate;
        else if (tempLeft < rightRange * scaleRate) tempLeft = rightRange * scaleRate;
        this.setData({
          bodyLeft: tempLeft
        })
      }
      this.setData({
        rangeEnable
      })
    },
    touchcancel(e) {
      if (!e.touches.length) {
        this.resetPosition();
        this.moveMotionEnd();
      }
    },
    resetPosition() {
      if (this.data.withAnime) clearTimeout(this.data.withAnime)
      this.setData({
        withAnime: setTimeout(() => {
          this.setData({
            withAnime: false
          })
        }, 400),
        bodyLeft: 0
      })
    },
    moveMotionEnd() {
      this.data.moveInfo.startTouch = false;
      this.data.moveInfo.isMove = false;
      this.data.moveInfo.yMove = false;
      this.data.moveInfo= this.data.moveInfo;
    },

  }
})

function getDistance(x1, y1, x2, y2) {
  return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2))
}